package org.gwt.grin.client.features;

import org.gwt.grin.client.Feature;
import org.gwt.grin.client.commands.Command;
import org.gwt.grin.client.util.Graphics;

/**
 * Modifies a child feature by applying an alpha value when drawing in it. This
 * lets you animate a fade-in and fade-out effect. It works be specifying alpha
 * values at a few keyframes, and doing linear interpolation between those
 * keyframes.
 * 
 * @author Bill Foote (http://jovial.com)
 * @author ggeorg
 */
public class Fade extends Modifier {

	public final static int ALPHA_FIELD = 0;

	protected InterpolatedModel model;

	private int lastAlpha, currAlpha;

	public Fade(String name, InterpolatedModel model, Feature part,
			Command[] endCommands) {
		super(name, part);
		this.model = model;
		this.model.endCommands = endCommands;
	}

	public InterpolatedModel getModel() {
		return model;
	}
	
	@Override
	protected int setSetupMode(boolean mode) {
		return super.setSetupMode(mode);
	}

	@Override
	protected void setActivateMode(boolean mode) {
		if (mode) {
			// Setup initial values
			lastAlpha = Short.MIN_VALUE;
			currAlpha = 0;
			model.activate();
		} else {
			model.deactivate();
		}
		super.setActivateMode(mode);
	}

	@Override
	public void nextFrame() {
		model.nextFrame();

		currAlpha = model.getField(ALPHA_FIELD);
		if (currAlpha > 255) {
			currAlpha = 255;
		}
		if (currAlpha < 0) {
			currAlpha = 0;
		}
		if (currAlpha != lastAlpha) {
			markAsChanged();
		}

		super.nextFrame();
	}

	@Override
	public void paintFrame(Graphics gc) {
		if (currAlpha != lastAlpha) {
			int old = gc.getOpacity();
			gc.setOpacity(currAlpha);
			part.paintFrame(gc);
			gc.setOpacity(old);
			lastAlpha = currAlpha;
		} else {
			part.paintFrame(gc);
		}
	}
}
